Minja

如何用自然语言进行 Google 搜索

如果你经常处理大宗任务,全程键盘输入的操作连贯性会比鼠标更好;在键盘录入中,自然语言的使用又可以进一步提升操作速度。很多工具都对自然语言有了很好的支持,有些甚至凭此在同类工具中脱颖而出:

  • 日程管理领域,Fantastical 以自然语言添加日程为傲,打一行字就能设置日程的标题、日期、优先级等属性。
  • 任务管理领域,Todoist 支持通过自然语言记录任务,经典用法是一次记录、分配给全团队的各个人员。
  • 文件搜索领域,Spotlight 特色是可以用自然语言进行文件过滤,比如输入 昨天下载的文件 来找文件。

不过,搜索引擎这个和我们朝夕相处的功能似乎很少得到自然语言的青睐1

实际上现代的搜索引擎多少都支持自然语言,但往往限于识别「和」「为什么」「哪里」这些副词或代词,和我们今天要精确控制的时间、语言有很大不同
 ,许多搜索设置仍需要在图形菜单里点击。如果你想找一篇 2015 年前后的新闻,还得在工具菜单里面一路点到 4 年前(手机干脆不支持)。

相信我们的读者多数都想兼顾搜索操作的速度搜索结果的精度,为此我制作了一套自然语言搜索动作,只需要在搜索关键词后跟上简单后缀,就能限定 Google 搜索结果的距今时限、日期范围或所用语言。动作可以无缝集成在各种 Mac 自动化工具上,也可以在 iOS 的经典文本处理工具 Drafts 中使用2

核心代码 Windows 可用,但考虑到涉及和特定浏览器交互,我又没有 Windows 设备,故无法提供成品
 

在 Drafts 中使用自然语义进行搜索

下面我们先了解一下语法和动作的使用,日常使用的话看完这部分就差不多;随后会用两节内容分析一下动作的设计思路,需要自定义的读者可以从中找到捷径。

语法规则

虽然美名其曰「自然语言」,实际上自动化工具并没有真的「听懂」你的话3

没有用到任何花哨的人工智能模块
 ,我们还是要遵循一些语法规则。好在这些规则不多,也容易用。由于 iOS 上的 Drafts 版不需要任何设置就能使用,这节就以它为例进行语法展示。

如文章开头所展示的一样,把搜索关键词和自然语言语法记录在 Drafts 草稿的同一行中,然后运行「Google it with natural language」动作即可按条件进行搜索。

针对搜索中最常见的几类过滤条件,我设计了这几组语法参数:

  1. 设置距今时限:限制搜索结果的时间为距今多久,找新闻时经常用到,比如限定搜索最近6 小时 h6,就能避免明日黄花混进搜索结果。具体可选这些参数:
    1. 限定年份ynn 表示具体要几年,比如最近两年就用 y2,只搜最近一年的话则不填 n,单用一个 y 即可。下面几项形式也一样。
    2. 限定月份mn
    3. 限定周数wn
    4. 限定天数dn
    5. 限定小时hn
  2. 设置日期范围:比上一组更加精确的时间条件,可以具体到两个日期之间4
    Google 有个 datarange 语法,但过滤结果似乎并不准,而且所采取的日期格式也不常用,故另起炉灶
     。使用空格隔开的两个短日期作为参数即可,比如搜今年四月一日到五月一日期间就是: 2019–04–01 2019–05–01
  3. 设置结果语言:限制结果,适合滤掉看不懂的内容,比如日文和中文常出现字同义不同的情况,我就限定只看自己需要的 中文 结果。动作默认只设置了 中文英文,需要其他语言的话看后两节介绍自行添加。

Google 搜索的过滤条件当然不止这些,不过常见的文件类型、所在站点都可以直接当关键词输入,没必要多此一举为它们设计自然语言语法。

注意,每组语法参数之间需要用空格   隔开,搜索关键词和语法之间同样也要隔开。比较推荐的写法是先写完所有关键词,空一格后再开始加上自然语言语法参数。尽管脚本也能成功识别混在一起的内容,但总有我没考虑到的特殊文本组合,还是按规矩出牌比较保险。

下面来看两个例子,相信看完后对于搜索语法就没什么疑问了。

  1. 只用动作自带的语法:搜索近两个月有关 JavaScript 的中文结果:
    JavaScript m2 中文
    搜索参数对应的搜索结果设置
  2. 结合 Google 自己的搜索语法:搜索近一年,少数派所发布关于 PDF 的文章。其中,site:sspai.com 用了 Google 原生语法,表示仅搜索少数派的内容
    site:sspai.com PDF y1
    结合了 Google 自带语法的四然语言搜索

只要掌握 关键词+自然语言参数 的组合,再配合上 Google 自带的几条语法,就可以在保持搜索的精度的同时大大提升操作流畅度。Google 语法可参我以前写过的《如何提高搜索的精度与速度》一文,没订阅过 Power+ 1.0 的读者也可以在网上搜到网友整理的语法,不一定要为此破费。

iOS 端实现:基于 Drafts

说起来是「自然语言」,实现起来主要就是检查有没有输入特定参数,这事儿交给 JavaScript 比较合适,而且写好的代码在 iOS 和 macOS 上都可以用,少走回头路。

在 iOS 运行 JavaScript 的理想选择是 Drafts,而且它的界面很干净,也适合输入大串关键词和参数。成品搜索动作由一段 JavaScript 代码一个打开 URL 的步骤组成,除了头尾涉及和 Drafts 交互的少量代码,JavaScript 脚本核心部分和 Mac 版是通用的。

这一节我们先简单看一下代码的整体思路,然后对于其中可以自定义的部分进行专门说明,最后再分享一个 Drafts 的自动化动作模板套件,方便有能力自己折腾的读者。

整体思路

脚本头尾是拿来和 Drafts 交互数据的,稍后介绍 Drafts 模板时专门讲,现在先来看实现自然语言搜索的部分。

核心代码所做的事情,就是把我们输入的简单参数「翻译」成 Google 能读懂的 URL 参数。我们所谓的自然语言只是对于使用者而言,而最终体现在 Google 的搜索 URL 中的则是一串规整却对普通人不怎么友好的参数——比如我们想搜最近两个月的内容,输入的是 m2,翻译到 URL 中则是 &tbs=qdr:m2

Google 搜索 URL 的组成

除了简单的日期,还有详细日期范围、结果语言等参数,也可以交给 JavaScript 脚本来「翻译」。总体上,脚本所做的事就是不断检查有没有符合格式的自然语言参数,然后译为 Google 可以理解的形式

  1. 橙色部分:检查有没有输入日期自然语言参数,有的话就翻译成日期搜索 URL 参数。
  2. 粉色部分:检查有没有输入日期范围参数,并翻译
  3. 绿色部分:检测有无结果语言参数,并翻译
  4. 蓝色部分:把参数从输入中剔除,剩余部分作为关键词
  5. 紫色部分:组合成 搜索 URL+关键词+搜索参数 URL 形式。为了照顾特殊符号和东亚字符,后续还有一步 URL 编码(encode)的操作。

注:粉色部分表示日期参数范围的代码随时会随着 Google 的动作进行微调,使用时不会有任何影响。之后 Google 有更新语法时,本文动作也会在 GitHub 上尽快发布更新。

脚本简析

最后得到的搜索 URL 是关键,接着就可以依据所用的自动化工具,放到网页里面打开查看。在 Drafts 中我们可以后接一个「URL」步骤直接打开 URL。Drafts 内置了 Safari View Controller,能够在应用内直接预览搜索结果,你所获得的动作默认也是这个设置。当然,喜欢在浏览器中查看搜索结果也可以,只需要取消勾选下图的「Open in Drafts」选项。

URL 步骤

至于「URL」步骤是如何从 JavaScript 获得搜索 URL 的,留到最后模板部分统一讲。

添加自定义结果语言

本文所提供的脚本只提供 中文英文 两个搜索结果语言参数,理所当然,你可以添加其他的语言。

以把 英文 改成其他语种为例5

当然可以保留英文选项,令起一个新语种
 ,首先找到 //检查语言参数 开始的这部分的代码(绿色部分),连着剔除自然语言参数的部分(蓝色部分),一共需要修改这几处:

  1. 修改结果语言参数的样式名称:将三处 regLanguageEN 改成 自定义语言样式,最后一处在删除自然语言参数的代码中(下面代码块的最后一行)。实际使用时尽量用英文,下面几条也同理。

  2. 修改具体要查找的参数:将 英文 改成 自定义语种

  3. 修改对应的 Google 搜索 URL 参数:将 lang_en 改成所需语种的 URL 参数,具体可在 这里 找到。

    //检查语言参数 var regLanguageCN = /\s中文/ var 自定义语言样式 = /\s自定义语种/ if (searchQuery.match(regLanguageCN)){ var langQuery = “&lr=lang_zh-CN” } else if (searchQuery.match(自定义语言样式)){ var langQuery = “&lr=语言参数” } else { var langQuery = “” }

    var pureQuery = searchQuery.replace(regDate,‘’).replace(regDaterange,‘’).replace(regLanguageCN,‘’).replace(自定义语言样式,‘’)

这样修改之后,就可以将搜索结果限定为自己需要的其他语言了。下图是一个仅检索日文内容的示例,其他语种的使用者也可以制作专用搜索参数。

限制搜索结果为日文

一个 Drafts 自动化模板套件

为求雨露均沾,前文讲到如何获取 JavaScript 步骤中的数据时就戛然而止,先转到了更通用的自定义语言部分。这里再给各位 Drafts 用户补上相关内容。

有必要说明一下,在 Drafts 的 JavaScript 步骤中也可以直接打开网页,但是完全靠代码来做事似乎有点浪费 Drafts 原生功能的发挥空间,何况对不熟悉 JavaScript 的读者也不友好。我推荐的方案,则是结合 JavaScript 和 Drafts 的标签,既能保留脚本的强大功能,又可以在 URL 等步骤中通过标签方便地使用各种数据6

很大程度上,Drafts 的标签作用和变量是一样的,都可以视作用于保存各种数据的「篮子」
 。下面红色高亮部分就是一个泛用的 JavaScript&标签模板。

从 JavaScript 脚本传递数据出去的模板

Drafts 里的标签都是 [[标签名]] 的样式,除了自带的草稿标题 [[title]]、内容 [[content]],还可以自己设置标签。在 JavaScript 脚本末尾加入上图左侧末尾的代码,就可以创建一个标签供本动作后续步骤使用(不会影响其他的动作):

draft.setTemplateTag("标签名","标签内容")

在「URL」步骤中我们可以看到 [[jsResult]] 这一标签,通过它就能获得整合出来的 Google 搜索 URL。从分析输入的关键词到最后的搜索,整个过程就此完成。

Mac 端实现和注意事项

由于搜索脚本完全用 JavaScript 写成,理论上任何支持 js 的工具都可以使用。不过最理想的工具载体还是各种启动器,LaunchBar、Alfred 这些启动工具本身就是一个输入框,配合自然语言工作起来严丝合缝。

启动器和自然语言搜索配合最舒服

LaunchBar 和 Alfred 两版的操作略有不同,这里还是简单介绍一下:

  1. LaunchBar 版:输入「Google Natural Language Search」的前几个字母,直到出现这一动作为止,按下空格继续按语法输入关键词和参数来搜索。
    在 LaunchBar 中用自然语言搜索
  2. Alfred 版:输入 goo 关键词来显示「Google Natural Language Search」工作流(workflow),空一格后输入关键词和参数,按下回车即可搜索。
    在 Alfred 中使用自然语言进行 Google 搜索

使用时需要注意一个细节,在没开启 Safari 时,LaunchBar 或 Alfred 会先停顿一下来打开浏览器,接着再开启搜索页面。如果遇到搜索框有几秒钟没反应,一般就是浏览器没打开,并不是卡顿或出错。Mac 上的自然语言搜索整体功能和 Drafts 保持一致,不过在 Mac 上可以随时呼出搜索框,这种有人在身边待命的感觉更舒服些。

搜索语法对于的过滤条件

设置专用域名后缀

两个版本的动作代码都差不多,就不再重复分析,需要自定义结果语言范围的读者可以参考 Drafts 部分。下面,我们专注一个 Mac 端的特殊情况:根据所处网络,为搜索动作设置对应地区

在 Drafts 版的动作中,最终搜索 URL 的开头就是常见的 Google 搜索前半部分:

https://www.google.com

一般来说,不管使用者身处哪个国家,都会跳转到预期的搜索结果页面。但是电脑上可能不太一样,视所处国家或网络状况需不同,搜索 URL 的域名可能要改动,比如在香港的朋友就需要将 .com 改成 .hk不然自然语言参数可能会失效。就拿香港地区为例,脚本生成搜索 URL 部分的第一行(即红色高亮部分)需要修改为:

var searchURL = "https://www.google.hk/search?q=" + pureQuery + dateQuery + daterangeQuery + langQuery
修改搜索 URL

处于其他地区和网络环境下的读者,遇到自然语言参数无效时也可以这样修改。

自定义默认浏览器

另一个可以自己修改的地方是默认浏览器。两个动作所用的代码都是嵌在 JXA 中的标准 JavaScript,可以通过苹果的原生语法调用一部分软件控件,打开浏览器网页就用到了 JXA 语法:

var Safari = Application("Safari");
var doc = Safari.Document().make();
var win = Safari.windows[doc.name()];
win.currentTab.url = encodeURI_url

如果你想把浏览器改成别的,比如 Chrome,可以这么改:

var Chrome = Application("Chrome");
var doc = Chrome.Window().make();
var win = Chrome.windows[doc.name()];
win.currentTab.url = encodeURI_url

至于更多浏览器的用户,这里没法一一照顾过来,有需要的读者可以参考 这篇文章 中收录的语法细节。

此外,由于 Alfred 对于输入数据的处理和 LaunchBar 不同,所以你在脚本开头会看到一行专门的代码,它的作用是把输入的数组转换为普通字符串:

var searchQuery = argv.join()

不熟悉它们也无妨,不影响正常使用动作,不过有兴趣自己制作 Alfred workflow 的读者可以留意一下。

小结

前几周恰逢 Google I/O 大会,媒体报道基本是些通稿,甚至还有炒前几年冷饭的;为了获得更精确的搜索结果,我每天起床都搜一下 google I/O d1,便知道最近一天大会上大致又发布了哪些软硬件和服务。

这只是所谓「自然语言搜索」的一个小用例。在其他需要精确日期、时间或语言的场合,这一搜索方式同样能够发挥作用。


59

您好,为了保护少数派用户创造的内容、维护良好的社区氛围,我们将从 2019 年 6 月 10 日起实行新的《少数派评论规范》,具体内容您可以通过相关页面了解,感谢您对少数派的理解与支持。(๑•ᴗ•๑)

精选评论 (0)

我的评论

目录

语法规则

iOS 端实现:基于 Drafts

整体思路

添加自定义结果语言

一个 Drafts 自动化模板套件

Mac 端实现和注意事项

设置专用域名后缀

自定义默认浏览器

小结